﻿using System;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace TSharp.Core.Aop.Handler
{
    /// <summary>
    /// 异常的处理类
    /// </summary>
    public class ExceptionCallHandler : ICallHandler
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ExceptionCallHandler"/> class.
        /// </summary>
        /// <param name="messageTemplate">The message template.</param>
        /// <param name="policyName">Name of the policy.</param>
        /// <param name="order">The order.</param>
        public ExceptionCallHandler(string messageTemplate, string policyName, int order)
        {
            MessageTemplate = messageTemplate;
            PolicyName = policyName;
            Order = order;
        }

        /// <summary>
        /// 错误消息模板
        /// </summary>
        public string MessageTemplate { get; set; }

        /// <summary>
        /// Policy名称
        /// </summary>
        public string PolicyName { get; set; }

        #region ICallHandler Members

        /// <summary>
        /// Order in which the handler will be executed
        /// </summary>
        /// <value></value>
        public int Order { get; set; }

        /// <summary>
        /// Implement this method to execute your handler processing.
        /// </summary>
        /// <param name="input">Inputs to the current call to the target.</param>
        /// <param name="getNext">Delegate to execute to get the next delegate in the handler
        /// chain.</param>
        /// <returns>Return value from the target.</returns>
        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            IMethodReturn result = getNext()(input, getNext);
            if (result.Exception != null)
            {
                string message = MessageTemplate.Replace("{Message}", result.Exception.Message)
                    .Replace("{Source}", result.Exception.Source)
                    .Replace("{StackTrace}", result.Exception.StackTrace)
                    .Replace("{HelpLink}", result.Exception.HelpLink)
                    .Replace("{TargetSite}", result.Exception.TargetSite.ToString());
                var ex = new Exception(message, result.Exception);
                bool rethrow = ExceptionPolicy.HandleException(ex, PolicyName);
                if (rethrow)
                    throw result.Exception;
            }
            return result;
        }

        #endregion
    }
}